//201902104003邵潇漩
package bysj.controller.basic;

import bysj.domain.GraduateProject;
import bysj.service.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j;
import util.Condition;
import util.ControllerHelper;
import util.JSONUtil;
import util.Pagination;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;

@Slf4j
@WebServlet("/graduateProject.ctl")
public class GraduateProjectController extends HttpServlet {

    /**
     * POST, http://localhost:8080/bysj/graduateProject.ctl, 增加课题
     * 增加一个课题对象：将来自前端请求的JSON对象，增加到数据库表中
     *
     * {"title":"虚拟现实中碰撞处理的研究","score":90.0,"graduateProjectCategory_id":1,
     * "graduateProjectType_id":1,"graduateProjectStatus_id":1,"graduateProjectSource_id":1,
     * "graduateProjectTrueness_id":1,"teacher_id":1,"student_id":4,"year":2020}
     *
     *  可能的请求
     *      { "pagination": { "pageNo": 1, "pageSize": 2 },
     *      "conditionList": [{ "value": "研究","key": "title", "operator": "LIKE"},
     *      { "value": "4", "key": "student_id", "operator": "=" }
     *      ] }
     *
     * @param request 请求对象
     * @param response 响应对象
     * @throws ServletException
     * @throws IOException
     */

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //根据request对象，获得代表参数的JSON字串
        String graduateProject_json = JSONUtil.getJSON(request);
        //将request body解析为JSONObject对象
        JSONObject req_jsonObj = JSON.parseObject(graduateProject_json);
        //将JSON字串解析为GraduateProject对象
        GraduateProject graduateProjectToAdd = JSON.parseObject(graduateProject_json, GraduateProject.class);
        //创建JSON对象message，以便往前端响应信息
        JSONObject message = new JSONObject();
        //在数据库表中增加School对象
        try {
            if(req_jsonObj.get("pagination")!=null||req_jsonObj.get("conditionList")!=null){
                //读取分页信息，形成分页对象
                //从JSONObject对象中读取 “pagination” 键对应的值(JSONObject对象)
                Pagination pagination = ControllerHelper.getPagination(req_jsonObj);
                //从请求JSONObject对象中读取键“conditionList”对应的值(描述查询条件的JSONArray对象)
                List<Condition> conditionList = ControllerHelper.getConditions(req_jsonObj);
                //响应多个课题信息
                this.responseGraduateProjects(response, pagination, conditionList);
            }else {
                //从JSONObject对象中读取键“graduateProjectCategory_id”的值
                Object graduateProjectCategoryId_obj = req_jsonObj.get("graduateProjectCategory_id");
                int graduateProjectCategoryId_int = Integer.parseInt(graduateProjectCategoryId_obj.toString());
                graduateProjectToAdd.setGraduateProjectCategory(GraduateProjectCategoryService.getInstance().find(graduateProjectCategoryId_int));
                //从JSONObject对象中读取键“graduateProjectType_id”的值
                Object graduateProjectTypeId_obj = req_jsonObj.get("graduateProjectType_id");
                int graduateProjectTypeId_int = Integer.parseInt(graduateProjectTypeId_obj.toString());
                graduateProjectToAdd.setGraduateProjectType(GraduateProjectTypeService.getInstance().find(graduateProjectTypeId_int));
                //从JSONObject对象中读取键“graduateProjectStatus_id”的值
                Object graduateProjectStatusId_obj = req_jsonObj.get("graduateProjectStatus_id");
                int graduateProjectStatusId_int = Integer.parseInt(graduateProjectStatusId_obj.toString());
                graduateProjectToAdd.setGraduateProjectStatus(GraduateProjectStatusService.getInstance().find(graduateProjectStatusId_int));
                //从JSONObject对象中读取键“graduateProjectSource_id”的值
                Object graduateProjectSourceId_obj = req_jsonObj.get("graduateProjectSource_id");
                int graduateProjectSourceId_int = Integer.parseInt(graduateProjectSourceId_obj.toString());
                graduateProjectToAdd.setGraduateProjectSource(GraduateProjectSourceService.getInstance().find(graduateProjectSourceId_int));
                //从JSONObject对象中读取键“graduateProjectTrueness_id”的值
                Object graduateProjectTruenessId_obj = req_jsonObj.get("graduateProjectTrueness_id");
                int graduateProjectTruenessId_int = Integer.parseInt(graduateProjectTruenessId_obj.toString());
                graduateProjectToAdd.setGraduateProjectTrueness(GraduateProjectTruenessService.getInstance().find(graduateProjectTruenessId_int));
                //从JSONObject对象中读取键“teacher_id”的值
                Object teacherId_obj = req_jsonObj.get("teacher_id");
                int teacherId_int = Integer.parseInt(teacherId_obj.toString());
                graduateProjectToAdd.setTeacher(TeacherService.getInstance().find(teacherId_int));
                //从JSONObject对象中读取键“student_id”的值
                Object studentId_obj = req_jsonObj.get("student_id");
                int studentId_int = Integer.parseInt(studentId_obj.toString());
                graduateProjectToAdd.setStudent(StudentService.getInstance().find(studentId_int));

                GraduateProjectService.getInstance().add(graduateProjectToAdd);
                message.put("message", "增加成功");
            }
        }catch (SQLException e){
            message.put("message", "数据库操作异常");
            log.error("数据库操作异常:"+e);
        } catch(Exception e){
            message.put("message", "网络异常");
            log.error("网络异常:"+e);
        }
        //响应message到前端
        response.getWriter().println(message);
    }

    /**
     * DELETE, http://localhost:8080/bysj/graduateProject.ctl?id=1, 删除id=1的课题
     * 删除一个课题对象：根据来自前端请求的id，删除数据库表中id的对应记录
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        //读取参数id
        String id_str = request.getParameter("id");
        int id_int = Integer.parseInt(id_str);
        log.info("id="+id_int);
        //创建JSON对象message，以便往前端响应信息
        JSONObject message = new JSONObject();
        //到数据库表中删除对应的课题
        try {
            GraduateProjectService.getInstance().delete(id_int);
            message.put("message", "删除成功");
        }catch (SQLException e){
            message.put("message", "数据库操作异常");
            log.error("数据库操作异常:"+e);
        }catch(Exception e){
            message.put("message", "网络异常");
            System.out.println(e.getMessage());
            log.error("网络异常:"+e);
        }
        //响应message到前端
        response.getWriter().println(message);
    }


    /**
     * PUT, http://localhost:8080/bysj/graduateProject.ctl, 修改课题
     *
     * 修改一个课题对象：将来自前端请求的JSON对象，更新数据库表中相同id的记录
     *
     * {"id":2,"title":"某高校监考管理系统的设计与实现","score":75.0,"graduateProjectCategory_id":2,
     * "graduateProjectType_id":2,"graduateProjectStatus_id":2,"graduateProjectSource_id":2,
     * "graduateProjectTrueness_id":2,"teacher_id":2,"student_id":4,"year":2020}
     *
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doPut(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //根据request对象，获得代表参数的JSON字串
        String graduateProject_json = JSONUtil.getJSON(request);
        //将request body解析为JSONObject对象
        JSONObject req_jsonObj = JSON.parseObject(graduateProject_json);
        //将JSON字串解析为GraduateProject对象
        GraduateProject graduateProjectToUpdate = JSON.parseObject(graduateProject_json, GraduateProject.class);
        //创建JSON对象message，以便往前端响应信息
        JSONObject message = new JSONObject();
        //到数据库表修改School对象对应的记录
        try {
            //从JSONObject对象中读取键“graduateProjectCategory_id”的值
            Object graduateProjectCategoryId_obj = req_jsonObj.get("graduateProjectCategory_id");
            int graduateProjectCategoryId_int = Integer.parseInt(graduateProjectCategoryId_obj.toString());
            graduateProjectToUpdate.setGraduateProjectCategory(GraduateProjectCategoryService.getInstance().find(graduateProjectCategoryId_int));
            //从JSONObject对象中读取键“graduateProjectType_id”的值
            Object graduateProjectTypeId_obj = req_jsonObj.get("graduateProjectType_id");
            int graduateProjectTypeId_int = Integer.parseInt(graduateProjectTypeId_obj.toString());
            graduateProjectToUpdate.setGraduateProjectType(GraduateProjectTypeService.getInstance().find(graduateProjectTypeId_int));
            //从JSONObject对象中读取键“graduateProjectStatus_id”的值
            Object graduateProjectStatusId_obj = req_jsonObj.get("graduateProjectStatus_id");
            int graduateProjectStatusId_int = Integer.parseInt(graduateProjectStatusId_obj.toString());
            graduateProjectToUpdate.setGraduateProjectStatus(GraduateProjectStatusService.getInstance().find(graduateProjectStatusId_int));
            //从JSONObject对象中读取键“graduateProjectSource_id”的值
            Object graduateProjectSourceId_obj = req_jsonObj.get("graduateProjectSource_id");
            int graduateProjectSourceId_int = Integer.parseInt(graduateProjectSourceId_obj.toString());
            graduateProjectToUpdate.setGraduateProjectSource(GraduateProjectSourceService.getInstance().find(graduateProjectSourceId_int));
            //从JSONObject对象中读取键“graduateProjectTrueness_id”的值
            Object graduateProjectTruenessId_obj = req_jsonObj.get("graduateProjectTrueness_id");
            int graduateProjectTruenessId_int = Integer.parseInt(graduateProjectTruenessId_obj.toString());
            graduateProjectToUpdate.setGraduateProjectTrueness(GraduateProjectTruenessService.getInstance().find(graduateProjectTruenessId_int));
            //从JSONObject对象中读取键“teacher_id”的值
            Object teacherId_obj = req_jsonObj.get("teacher_id");
            int teacherId_int = Integer.parseInt(teacherId_obj.toString());
            graduateProjectToUpdate.setTeacher(TeacherService.getInstance().find(teacherId_int));
            //从JSONObject对象中读取键“student_id”的值
            Object studentId_obj = req_jsonObj.get("student_id");
            int studentId_int = Integer.parseInt(studentId_obj.toString());
            graduateProjectToUpdate.setStudent(StudentService.getInstance().find(studentId_int));

            GraduateProjectService.getInstance().update(graduateProjectToUpdate);
            message.put("message", "修改成功");
        }catch (SQLException e){
            message.put("message", "数据库操作异常");
            log.error("数据库操作异常:"+e);
        }catch(Exception e){
            message.put("message", "网络异常");
            log.error("网络异常:"+e);
        }
        //响应message到前端
        response.getWriter().println(message);
    }

    /**
     * GET, http://localhost:8080/bysj/graduateProject.ctl?id=1, 查询id=1的课题
     *
     *
     * GET, http://localhost:8080/bysj/graduateProject.ctl, 查询所有的课题
     * 把一个或所有课题对象响应到前端
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //创建JSON对象respMessage_jsonObj，以便往前端响应信息
        JSONObject respMessage_jsonObj = new JSONObject();
        //读取参数id
        String id_str = request.getParameter("id");
        try {
            //如果id_str != null, 说明请求某个课题对象
            if (id_str != null) {
                int id = Integer.parseInt(id_str);
                this.responseGraduateProject(id, response);
                log.info("id=" + id);
            } else {
                //响应多个课题对象
                this.responseGraduateProjects(response);
            }
        } catch (SQLException e) {
            respMessage_jsonObj.put("message", "数据库操作异常");
            //响应respMessage_jsonObj到前端
            response.getWriter().println(respMessage_jsonObj);
            //打印异常栈，方便调试
            log.error("数据库操作异常:"+e);
        } catch (Exception e) {
            respMessage_jsonObj.put("message", "网络异常");
            //响应respMessage_jsonObj到前端
            response.getWriter().println(respMessage_jsonObj);
            //打印异常栈，方便调试
            log.error("网络异常:"+e);
        }
    }
    //响应一个课题对象
    private void responseGraduateProject(int id, HttpServletResponse response)
            throws ServletException, IOException, SQLException {
        //根据id查找课题
        GraduateProject graduateProject = GraduateProjectService.getInstance().find(id);
        String graduateProject_json = JSON.toJSONString(graduateProject);
        //响应graduateProject_json到前端
        response.getWriter().println(graduateProject_json);
    }
    //响应所有课题对象
    private void responseGraduateProjects(HttpServletResponse response)throws ServletException, IOException, SQLException{
        //获得满足条件的所有课题
        Collection<GraduateProject> graduateProjects = GraduateProjectService.getInstance().findAll();
        String graduateProjects_json = JSON.toJSONString(graduateProjects, SerializerFeature.DisableCircularReferenceDetect);
        //响应graduateProjects_json到前端
        response.getWriter().println(graduateProjects_json);
    }
    //响应所有课题对象
    private void responseGraduateProjects(HttpServletResponse response,Pagination pagination,List<Condition> conditionList)
            throws ServletException, IOException, SQLException {
        //获得满足条件的所有课题
        Collection<GraduateProject> graduateProjects = GraduateProjectService.getInstance().findAll(pagination,conditionList);
        String department_json = JSON.toJSONString(graduateProjects,SerializerFeature.DisableCircularReferenceDetect);
        JSONObject response_json = new JSONObject();
        response_json.put("totalNum" ,pagination.getTotalNum());
        response_json.put("data",department_json);
        //响应response_json到前端
        response.getWriter().println(response_json);
    }
}
